package com.maiworld.api.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang.RandomStringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.dubbo.config.annotation.Reference;
import com.maiworld.pojo.TbNewtable;
import com.maiworld.pojo.TbOrder;
import com.maiworld.seller.service.NewtableService;
import com.maiworld.seller.service.OrderService;

import net.sf.json.JSONObject;
import wxutils.Constant;
import wxutils.WeChatUtil;
@RestController
public class wxPayController {

	
	
	@Reference
	private OrderService orderService;
	
	@Reference
	private NewtableService newtableService;
	
	/**
	 * 统一下单
	 * 第一步：获取到必要的参数
	 * 第二步：把获取到的参数保存到map集合里，为下一步做准备
	 * 第四步 远程调用微信支付接口，接受返回数据
	 * 这是进入支付页面时，还没有输入密码就执行了，主要是为了获取到微信返回的prepay_id 预支付交易会话标识，
	 * 有效期为两小时，也就是说，支付时要带着这个prepay_id去支付，没有这个支付不成功，输入支付密码后带着这个prepay_id
	 * 去二次签名。
	 * Map<String, Object> params, String ip, String out_trade_no, String url
	 */
    @RequestMapping("/weixin/payment")
    @ResponseBody
	public JSONObject unifiedOrder(@RequestParam(required = true) String openId,
			  @RequestParam(required = true) String status,
			  @RequestParam(required = true) Long order_id) {
    	
    	
    	TbOrder a = orderService.selectByPrimaryKey(order_id);
        
        a.getSignurl();    //签字的图片
        a.getUsername();   //学员姓名
        a.getPhone();    //学员手机号
        
        TbNewtable b = newtableService.selectByPrimaryKey(a.getNewsId());
        float price = Float.parseFloat(b.getPrice())*100;
        Integer pri = (int)price;
//        System.out.println(pri.toString());
        String total_fee1 =pri.toString();    //目前价格
        String body1 = b.getBname();     //商品描述   如：普通版，VIP班， 周末班
        String pic = b.getSignimgurl();  //合同图片
    	
    	
    	
		//第一步
		//公众账号ID  (微信支付分配的公众账号ID)
		String appID = Constant.appid;
		//微信支付分配的商户号
		String mch_id = Constant.mch_id;
		//异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
//		String notify_url = url;
		String notify_url = "https://apijx.maiworld.net/weixin/paycallback.do";
		//订单总金额，单位为分，
//		String total_fee = (String) params.get("total_fee");
		String total_fee = total_fee1;
		//商品描述
//		String body = (String) params.get("body");
		String body = body1;
		//随机字符串，长度要求在32位以内。
		String nonce_str = RandomStringUtils.randomAlphanumeric(20);
		
		String ip ="60.205.185.53";
		String openid = openId;
		String today = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
		String out_trade_no = mch_id + today + RandomStringUtils.randomAlphanumeric(8);//商户订单号
		String url = "";
		
		//第二部：把这些必须的参数获取保存到map集合里
		SortedMap<String, String> map = new TreeMap<>();
		map.put("appid", appID);
		map.put("mch_id", mch_id);
		map.put("nonce_str", nonce_str);
		map.put("body", body);
		map.put("total_fee", total_fee);
		map.put("notify_url", notify_url);
		map.put("openid", openId);
		//商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一
		map.put("out_trade_no", out_trade_no);
		//支付的交易类型
		map.put("trade_type", "JSAPI");		
		//调用微信支付API的机器IP，也就是商户的机器地址
		map.put("spbill_create_ip", ip);


		//第三步 
		// WeChatUtil.getSign(map)：通过这些参数调用逻辑传入参数按照字段名的 ASCII 码从小到大排序（字典序）
		//最后拼接上key得到字符串，并进行MD5运算，再将得到的字符串所有字符转换为大写，得到sign值signValue。(签名)
		//得到sign签名后把这些参数转成xml格式，以下的这些参数是必须的参数，为什么转成xml格式是因为微信那边定义了，我们必须定义xml格式
		StringBuilder xml = new StringBuilder();
		xml.append("<xml>");
		xml.append("<appid>").append(appID).append("</appid>");
		xml.append("<body>").append(body).append("</body>");
		xml.append("<mch_id>").append(mch_id).append("</mch_id>");
		xml.append("<nonce_str>").append(nonce_str).append("</nonce_str>");
		xml.append("<notify_url>").append(notify_url).append("</notify_url>");
		xml.append("<openid>").append(openId).append("</openid>");
		xml.append("<out_trade_no>").append(out_trade_no).append("</out_trade_no>");
		xml.append("<spbill_create_ip>").append(ip).append("</spbill_create_ip>");
		xml.append("<total_fee>").append(total_fee).append("</total_fee>");
		xml.append("<trade_type>JSAPI</trade_type>");
		xml.append("<sign>").append(WeChatUtil.getSign(map)).append("</sign>");
		xml.append("</xml>");

		//第四步 远程调用微信支付接口，接受返回数据
		JSONObject jOb = unifiedOrder(xml.toString());
		//paySign = MD5(appId=wxd678efh567hg6787
		//&nonceStr=5K8264ILTKCH16CQ2502SI8ZNMTM67VS
		//&package=prepay_id=wx2017033010242291fcfe0db70013231072
		//&signType=MD5&timeStamp=1490840662&key=qazwsxedcrfvtgbyhnujmikolp111111)
		Long timesta = System.currentTimeMillis()/1000;
		String paySignStr = "appId="+jOb.getString("appid")+"&nonceStr="+jOb.getString("nonce_str")+"&package=prepay_id="+jOb.getString("prepay_id")+"&signType=MD5&timeStamp="+timesta.toString()+"&key="+Constant.API_KEY;
//		System.out.println(paySignStr);
		String paySign = WeChatUtil.MD5(paySignStr);
		JSONObject result = new JSONObject();
		result.put("timeStamp", timesta.toString());
		result.put("nonceStr", jOb.getString("nonce_str"));
		result.put("package", "prepay_id="+jOb.getString("prepay_id"));
		result.put("signType", "MD5");
		result.put("paySign", paySign);
		return result;
	}
	
	/**
	 * 统一下单
	 */
	public static JSONObject unifiedOrder(String params) {
		//调用微信支付的接口
		String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		//远程调用，主要是为了安全
		String result = invokeHttpRemoteMethod(url, "POST", params);
		//最后微信返回的结果进行转成json格式
		return WeChatUtil.parseXml(result);
	}
	
	// 远程调用
	private static String invokeHttpRemoteMethod(String url, String method, String params) {
		return WeChatUtil.remoteVisit(url, method, params);
	}

}
